/**
 * 项目相关中间件
 *
 * Created by snowingsea on 2020/02/08.
 */
const projects = require('./../../models/projects');
const projectHistories = require('./../../models/project-histories');
const PhoenixError = require('./../../models/phoenix-error');
const users = require('./../../models/users');

/**
 * 判断URL参数中项目Id是否存在
 * @param req
 * @param res
 * @param next
 */
function requireProjectExist(req, res, next) {
  if (!req.params.projectId) {
    next(new PhoenixError('invalid request', 'Missing parameters. "projectId" is required'));
    return;
  }
  projects.getProject(req.params.projectId)
    .then((project) => {
      if (!project) {
        return Promise.reject(new PhoenixError('not found', 'Not found, project not found'));
      }
      req.$project = project;
      return Promise.resolve();
    })
    .then(() => {
      next();
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

/**
 * 要求当前项目的访问权限
 * @param req
 * @param res
 * @param next
 */
function requireProjectAccess(req, res, next) {
  if (req.$token.userId.toString() === req.$project.creatorId.toString()
    || (req.$project.sharedUserGroup && [...req.$project.sharedUserGroup].map((i) => i.toString()).indexOf(req.$token.userId.toString()) >= 0)) {
    next();
    return;
  }
  users.getUserByName(global.config.sampleManager.username)
    .then((superUser) => {
      if (superUser._id.toString() !== req.$project.creatorId.toString()) {
        return Promise.reject(new PhoenixError('not found', 'The project is not yours'));
      }
      return Promise.resolve();
    }).then(() => {
      next();
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

/**
 * 要求当前项目的可编辑
 * @param req
 * @param res
 * @param next
 */
function requireProjectAvailable(req, res, next) {
  let err;
  switch (req.$project.status) {
    case projects.statusKind.frozen:
      err = new PhoenixError('forbidden', 'The project is frozen');
      break;
    case projects.statusKind.deleting:
      err = new PhoenixError('forbidden', 'The project is deleting');
      break;
    default:
      break;
  }
  next(err);
}

/**
 * 要求当前项目历史是否存在
 * @param req
 * @param res
 * @param next
 */
function requireProjectHistoryExist(req, res, next) {
  if (!req.params.projectHistoryId) {
    next(new PhoenixError('invalid request', 'Missing parameters. "projectHistoryId" is required'));
    return;
  }

  projectHistories.getHistory(req.params.projectHistoryId)
    .then((projectHistory) => {
      if (!projectHistory) {
        return Promise.reject(new PhoenixError('not found', 'Not found, project history not found'));
      }
      req.$projectHistory = projectHistory;
      return projects.getProject(projectHistory.projectId);
    })
    .then((project) => {
      if (!project) {
        return Promise.reject(new PhoenixError('not found', 'Not found, project not found'));
      }
      req.$project = project;
      return Promise.resolve();
    })
    .then(() => {
      next();
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

/**
 * Export model definition object.
 */
module.exports = {
  requireProjectExist,
  requireProjectAccess,
  requireProjectAvailable,

  requireProjectHistoryExist,
};
